<?
// function to safely trim null-terminated strings
// could just use trim () in this example though
function trim_c_string ($string) {
  $new = "";
  $len = strlen ($string);
  for ($x=0; $x<$len; $x++) {
    if ($string[$x] != "\0") $new .= $string[$x];
  }
  return $new;
}


// Function to remove the colour code data from a string
function remove_colour_codes($String){
  $ColCodes = array("^0","^1","^2","^3","^4","^5","^6","^7","^8","^9");
  $NewString = str_replace($ColCodes, "",$String);
  return $NewString;
}


// Function used by format_host_colours function to display correct colour value in html format
function get_colour($ColourNum){
  switch ($ColourNum) {
    case "0";
      $ColourName = "#000000"; //Black
      break;
    case "1";
      $ColourName = "#FF0000"; //Red
      break;
    case "2";
      $ColourName = "#00FF00"; //Pastel Green
      break;
    case "3";
      $ColourName = "#FFFF00"; //Yellow
      break;
    case "4";
      $ColourName = "#0000FF"; //Light Blue
      break;
    case "5";
      $ColourName = "#FF0080"; //Light Purple
      break;
    case "6";
      $ColourName = "#00FFFF"; //Turquoise
      break;
    case "7";
      // Remove comment marks on next line if not a white background
      //$ColourName = "#FFFFFF";    //White
      // Add Comment marks to next line if not a white background
      $ColourName = "#808080";    //Dark Grey
      break;
    case "8";
      $ColourName = "#00FF00"; //Pastel Green
      break;
  }
  return $ColourName;
}


// Function to replace the ^x codes in the Host name to show correct colours on the screen
function format_host_colours($HostName){
  //$len = strlen ($LfsHostlist);
  // Thanks to Tristiancliffe for this line. It is a refresh link
  for($i = 0; $i < strlen($HostName); $i++){
    if(substr($HostName, $i, 1) == "^"){
      $CharPos = strpos($HostName, "^", $i);
      $ColNum = substr($HostName, strpos($HostName, "^", $i) + 1,1);
      $ColourString = get_colour(substr($HostName, strpos($HostName, "^", $i) + 1,1));
      if($i == "0"){
        // If ^ found at the start of the host string remove the ^[num]
        $TmpString = substr($HostName,$i+2);
        // Add the html font code to the start of the string and append the
        // variable $TmpString with the ^[num] removed
        $HostName = "<font color='$ColourString'>".$TmpString;
      }
      else {
        // Get the left part of the string to the next ^[num]
        $LTmpString = substr($HostName,0,$i);
        // Get the right part of the string after the ^[num]
        $RTmpString = substr($HostName,$i+2);
        // Add the html close font and add the new html colour to the end of the
        // Left part of the string then add the right part of the string
        $HostName = $LTmpString."</font><font color='$ColourString'>".$RTmpString;
      }
    } 
  }
  // Close any html font tag left open in the above
  $HostName = $HostName."</font>";
  Return $HostName;
}


// function to find a specific server
function find_lfs_host($mHostname,$LfsWorld) {
  $LfsWorldLength = strlen ($LfsWorld);
  $Host;
  while ($x < $LfsWorldLength) {
    $LfsHostName = "";
	$nr_racers=0;
    //ophalen hostnaam (32 karakters)
    for ($y=0; $y<32; $y++) $LfsHostName .= $LfsWorld[$x++];
    $LfsHostName = trim_c_string ($LfsHostName);
    $Host['Naam'] = remove_colour_codes($LfsHostName);
    //kijken of het om een bepaalde server gaat (kleurcodes in het oog houden)
    //als de server gevonden is, dan worden alle gegevens van die server gelezen en bewaard in variabelen voor later gebruik
    // $LfsHostNameNoCol = remove_colour_codes($LfsHostName);
    if (!strcmp($Host['Naam'],$mHostname)) {
      //$Host['Naam'] = remove_colour_codes($LfsHostName);
      $Host['LfsNaam'] = $LfsHostName;
      $Host['HtmlNaam'] = format_host_colours($LfsHostName);
      // Type, Versie, Letter, TestId ophalen
      //$Host['Type'] = ord($LfsWorld[$x++]);      // 1 byte
      switch (ord($LfsWorld[$x++])) {
	    case "0";
	      $Host['Type'] = "old S1";
	      break;
	    case "1";
	      $Host['Type'] = "S1";
	      break;
	    case "2";
	      $Host['Type'] = "S2";
	      break;	      
	  }
      $Host['Versie'] = ord($LfsWorld[$x++])/10;    // 1 byte
      $Host['Letter'] = "&#" . ord($LfsWorld[$x++]);    // 1 byte
      $Host['TestId'] = ord($LfsWorld[$x++]);    // 1 byte
      // Track, Config, Reversed, Max players allowed
      $Track = ord($LfsWorld[$x++]);     // 1 byte
      $Config = ord($LfsWorld[$x++]);    // 1 byte
      $Reversed = ord($LfsWorld[$x++]);  // 1 byte
      $Tracks[00] = "Blackwood GP";
      $Tracks[01] = "Blackwood Rally X";
      $Tracks[10] = "South City Classic";
      $Tracks[11] = "South City Sprint 1";
      $Tracks[12] = "South City Sprint 2";
      $Tracks[13] = "South City Long";
      $Tracks[14] = "South City Town";
      $Tracks[20] = "Fern Bay Club";
      $Tracks[21] = "Fern Bay Green";
      $Tracks[22] = "Fern Bay Gold";
      $Tracks[23] = "Fern Bay Black";
      $Tracks[24] = "Fern Bay Rally X";
      $Tracks[25] = "Fern Bay Rally X Green";
      $Tracks[32] = "Drag";
      $Tracks[33] = "Drag X 8";
      $Tracks[40] = "Kyoto Oval";
      $Tracks[41] = "Kyoto National";
      $Tracks[42] = "Kyoto GP Long";
      $Tracks[50] = "West Hill International";
      $Tracks[60] = "Aston Cadet";
      $Tracks[61] = "Aston Club";
      $Tracks[62] = "Aston National";
      $Tracks[63] = "Aston Historic";
      $Tracks[64] = "Aston GP";
      $Tracks[65] = "Aston Grand Touring";
      $Tracks[66] = "Aston North";
      $Host['Track'] = $Tracks["$Track$Config"];
      if ($Reversed=="1") $Host['Track'] .= " rev";
	  // maxplayers (1byte)
      $Host['Maxplayers'] = ord($LfsWorld[$x++]);
      // Cars (4 bytes)
      $Cars[1] = ord($LfsWorld[$x++]); // van rechts naar links: bit3=BF1 , bit2=FZR , bit 1=XRR
      $Cars[2] = ord($LfsWorld[$x++]); // bit8=FXR , bit7=FO8, bit6=UFR , bit5=XFR , bit4=FOX , bit3=FZ5 , bit2=RAC , bit1=UF1
      $Cars[3] = ord($LfsWorld[$x++]); // bit8=MRT , bit7=LX6, bit6=LX4 , bit5=FXO , bit4=RB4 , bit3=XRT , bit2=XRG , bit1=XFG 
      $Cars[4] = ord($LfsWorld[$x++]); // hier zou normaal niets in staan
      //wagens uit bits halen (cars13=BF1 , bit12=FZR, bit11=XRR, bit28=FXR, bit27=FO8 , ..., bit32=XRG , bit 31=XFG)
      for ($j=1; $j<5 ; $j++) {
        $temp= $Cars[$j];
        for ($k=1; $k<9;$k++) {
	      $Rest = $temp&1; // 2 % 2 = 0
          $Host['Cars']["$j$k"] = $Rest;
          $Deling = ($temp-$Rest)/2; // (255-1) / 2 = 127
          $Cars[$i] = $Deling; // 127
		  $temp=$Deling; 
	    }
	  }
	  $Wagens = array(
	    array("XRR","FZR","BF1"),
	    array("UF1","RAC","FZ5","FOX","XFR","UFR","FO8","FXR"),
	    array("XFG","XRG","XRT","RB4","FXO","LX4","LX6","MRT"));
	  $Host['All Cars'];
	  for ($j=1; $j<5 ; $j++) {
	    for ($k=1; $k<9;$k++) {
		  if ($Host['Cars']["$j$k"]=="1") $Host['All Cars'] .= $Wagens[$j-1][$k-1] . " ";
		}
	  }
      // Rules (4 bytes)
      //for ($i=0; $i<4; $i++)$Rules .= $LfsWorld[$x++];
      //$Host['Regels'] = ord($Rules);
      $Rules[1] = ord($LfsWorld[$x++]); // bit7=MustPit , bit6=MidRacejoin, bit5=Modified , bit4=Private , bit3=Qualify , bit2=Can_Select , bit1=Can_Vote
      $Rules[2] = ord($LfsWorld[$x++]); // leeg
      $Rules[3] = ord($LfsWorld[$x++]); // leeg 
      $Rules[4] = ord($LfsWorld[$x++]); // leeg
      $temp= $Rules[1];
      for ($k=1; $k<9;$k++) {
	    $Rest = $temp&1; // 2 % 2 = 0
        $Rules["1$k"] = $Rest;
        $Deling = ($temp-$Rest)/2; // (255-1) / 2 = 127
        $Cars[$i] = $Deling; // 127
		$temp=$Deling; 
	  }
	  $Rules["14"] ? $Host['Status'] = "private" : $Host['Status'] = "publiek";
	  $Host['JoinUrl'] = "lfs://|" . (str_replace(" ","+",$Host['Naam'])) . "|" . $Rules["14"] . "|" . $Host['Type'] . "/";
	  $Host['Opties'] = "";
	  $Rules["11"] ? $Host['Opties'] .= "Er kan gestemd worden. ": "Er kan niet gestemd worden. ";
	  $Rules["12"] ? $Host['Opties'] .= "Track kan gekozen worden. ": "Track kan niet veranderd worden. ";
	  $Rules["13"] ? $Host['Opties'] .= "Qualify staat aan. ": "Qualify staat af. ";
	  $Rules["15"] ? $Host['Opties'] .= "Server is gemod. ": "Geen mods aanwezig. ";
	  $Rules["16"] ? $Host['Opties'] .= "MidRace join niet mogelijk. ": "Midrace join mogelijk. ";
	  $Rules["17"] ? $Host['Opties'] .= "Moet gepit worden." : "Pitten is vrij.";
	  
	  // switch nog uitwerken (zie stats v1.2)
	  // Laps (1 byte)
	  $Laps = ord($LfsWorld[$x++]);
	  if ($Laps=="0") $Host['Laps'] ="Practice";
	  if ($Laps>"0" && $Laps<"101") $Host['Laps'] = "$Laps ronden";
	  if ($Laps>"100" && $Laps<"191") $Host['Laps'] = ($Laps-100)*10+100 . " ronden";
	  if ($Laps>"190" && $Laps<"239") $Host['Laps'] = ($Laps-190) . "uur";
	
	  //stats nog uitwerken (zie stats v1.2)
	  // Qualminutes (1byte)
	  $Host['QualMinutes'] = ord($LfsWorld[$x++]);
	  // 2 spare bytes overslaan
	  $x =$x+2;
	  //nr of racers (1 byte)
	  $Host['nr_racers'] = ord($LfsWorld[$x++]);
	  // Elke speler uit de lijst halen (1 speler = max 24 karakters)
	  for ($i=0;$i<$Host['nr_racers']; $i++) {
	    $Piloten[$i]="";
	    for ($j=0; $j<24; $j++) $Piloten[$i] .= $LfsWorld[$x++];
	    $Piloten[$i] = trim_c_string($Piloten[$i]);
	  }
	  $Host['Piloten'] = $Piloten;
	}
    else {
      // echo "Host niet correct: " . $LfsHostName;
      $x += 20; // skip data
      $nr_racers = ord ($LfsWorld[$x++]);
      // skip some more (pilot names)
      $x += ($nr_racers * 24);
	}
  }
  return $Host;
}

/*

-------------
?action=hosts
-------------
(get host list & information and online racers)

requires:	-
optional:	-
returns:	HOST STRUCT:

HOSTNAME        char[32]
TMLT	        byte[4]
TCRM            byte[4] // Track, Config, Reversed, Max players allowed
CARS            ulong (4 bytes)
RULES           ulong (4 bytes)
LAPS            byte [1]
QUALMINS        byte [1]
spare           byte [1]
spare           byte [1]
NROFRACERS      byte[1]
RACERNAMES      char[24 * NROFRACERS]

LAPS work like this:
    L is the given Laps value
    0=practice
    1-100=laps
    101-190=110-1000 laps...  100+(L-100)*10
    191-238=1-48 hours... L-190

TMLT means:
Type		0 : old S1 / 1 : new S1 / 2 : S2
Main		version times 10 (e.g. 3 means version 0.3)
Letter		e.g. 'H' in 0.3H
TestId		zero : official / non-zero : test patch id

(*) TRC is in numbers:
000 = bl1
001 = bl1r
010 = bl2
..
220 = fe3
221 = fe3r
etc.
 
cars bits:
    XFG          1
    XRG          2
    XRT          4
    RB4          8
    FXO          16
    LX4          32
    LX6          64
    MRT          128
    etc          etc

rules bits :
    CAN_VOTE     1
    CAN_SELECT   2
    QUALIFY      4
    PRIVATE      8
    MODIFIED     16
    MIDRACEJOIN  32
    MUSTPIT      64
*/
?>